package com.synergy.stockflow.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.synergy.stockflow.annotation.Log;
import com.synergy.stockflow.annotation.LogModule;
import com.synergy.stockflow.entity.SysDictItem;
import com.synergy.stockflow.entity.SysDictType;
import com.synergy.stockflow.entity.bo.SysDictItemQueryBO;
import com.synergy.stockflow.entity.bo.SysDictTypeQueryBO;
import com.synergy.stockflow.entity.vo.SysDictItemVO;
import com.synergy.stockflow.entity.vo.SysDictTypeVO;
import com.synergy.stockflow.model.Result;
import com.synergy.stockflow.service.SysDictItemService;
import com.synergy.stockflow.service.SysDictTypeService;
import com.synergy.stockflow.service.SysUserService;
import com.synergy.stockflow.service.impl.SysDictTypeServiceImpl;
import com.synergy.stockflow.utils.ConvertUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Optional;

@Tag(name = "枚举字典", description = "对枚举字典及枚举值进行数据库操作")
@RestController
@RequestMapping("/dict")
@LogModule(name = "字典管理")
public class SysDictController {

    @Autowired
    private SysDictTypeService sysDictTypeService;

    @Autowired
    private SysDictItemService sysDictItemService;

    @Autowired
    private SysUserService sysUserService;

    @Operation
            (
                    summary = "查询数据字典类型", // 简要描述（必填）
                    description = "根据查询条件、页码及每页条数查询当前页码存储字典类型数据的Page对象", // 详细说明
                    operationId = "dict:page", // 操作ID（推荐）
                    tags = {"枚举字典"}, // 接口分组标签（必填）
                    responses = {
                            @ApiResponse(
                                    responseCode = "200", // HTTP状态码（必填）
                                    description = "成功查询数据", // 响应描述
                                    content =
                                    @Content( // 返回的数据结构
                                            mediaType = "application/json",
                                            schema = @Schema(
                                                    implementation = Result.class
                                            )
                                    )
                            ),
                            @ApiResponse(
                                    responseCode = "400",
                                    description = "参数读取无效",
                                    content =
                                    @Content( // 返回的数据结构
                                            mediaType = "application/json",
                                            schema = @Schema(
                                                    implementation = Result.class
                                            )
                                    ))
                    },
                    parameters = {
                            @Parameter(
                                    name = "current", // 参数名（必填）
                                    description = "当前页码（从1开始）", // 参数描述（必填）
                                    required = false, // 是否必传（必填）
                                    in = ParameterIn.QUERY, // 参数在请求中的位置（DEFAULT, PATH, QUERY, HEADER, COOKIE）
                                    schema = @Schema(
                                            type = "integer",
                                            defaultValue = "1",
                                            minimum = "1",
                                            example = "1"
                                    ) // 数据类型
                            ),
                            @Parameter(
                                    name = "size",
                                    in = ParameterIn.QUERY,
                                    required = false,
                                    schema = @Schema(type = "integer"),
                                    description = "每页条数"
                            )
                    }
            )
    @GetMapping("/view")
    @Log(title = "分页查询枚举字典类型")
    public Result<Page<SysDictType>> view(
            @RequestParam(name = "current", defaultValue = "1") Integer current,
            @RequestParam(name = "size", defaultValue = "5") Integer size
    ) {
        Page<SysDictType> page = sysDictTypeService.page(new Page<>(current, size));
        return Result.success(page);
    }

    /**
     * 分页获取字典类型列表（对外 API 接口）
     *
     * <p>接收前端传入的分页与查询条件，查询数据库中符合条件的字典类型数据，
     * 并将实体对象转换为视图对象（VO）后返回，确保接口响应字段安全、清晰、易读。</p>
     *
     * <p>支持的查询条件包括：</p>
     * <ul>
     *     <li>类型编码：模糊匹配</li>
     *     <li>类型名称：模糊匹配</li>
     *     <li>状态：启用（1）/ 禁用（0）</li>
     *     <li>是否删除：默认只查未删除数据</li>
     * </ul>
     *
     * @param query 请求体参数，封装了分页信息和查询条件 {@link SysDictTypeQueryBO}
     * @return {@link Result<Page< SysDictTypeVO >>} 统一响应结果，包含分页的字典类型视图数据
     * @http POST /dict/list
     * @status 200 返回成功，data 中包含分页数据
     * @status 500 查询异常
     * @example 请求示例：
     * <pre>
     * {
     *   "current": 1,
     *   "size": 10,
     *   "typeCode": "",
     *   "typeName": "",
     *   "status": 1
     * }
     * </pre>
     * @author YourName
     * @see SysDictTypeServiceImpl#convert(SysDictType)
     * @see SysDictTypeVO
     * @since 2025-04-05
     */
    @PostMapping("/list")
    public Result<Page<SysDictTypeVO>> page(@RequestBody SysDictTypeQueryBO query) {
        Page<SysDictType> page = new Page<>(query.getCurrent(), query.getSize());
        Page<SysDictTypeVO> typePage = sysDictTypeService.pageByQuery(page, query);
        return Result.success(typePage);
    }

    @PostMapping("/item")
    public Result<Page<SysDictItemVO>> page(@RequestBody SysDictItemQueryBO bo) {
        Page<SysDictItem> page = new Page<>(bo.getCurrent(), bo.getSize());
        LambdaQueryWrapper<SysDictType> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysDictType::getTypeCode, bo.getTypeCode());
        Optional<SysDictType> opt = sysDictTypeService.getOneOpt(queryWrapper);
        if (opt.isPresent()) {
            SysDictType sysDictType = opt.get();
            LambdaQueryWrapper<SysDictItem> itemQueryWrapper = new LambdaQueryWrapper<>();
            itemQueryWrapper.eq(SysDictItem::getTypeId, sysDictType.getDictTypeId());
            if (bo.getItemKey() != null) itemQueryWrapper.and(consumer -> {
                consumer.like(SysDictItem::getLabel, bo.getItemKey());
                consumer.or().like(SysDictItem::getItemKey, bo.getItemKey());
                consumer.or().like(SysDictItem::getItemValue, bo.getItemKey());
            });
            if (bo.getStatus() != null) itemQueryWrapper.and(consumer -> consumer.eq(SysDictItem::getStatus, bo.getStatus()));
            itemQueryWrapper.orderByDesc(SysDictItem::getSort)
                    .orderByDesc(SysDictItem::getUpdateTime)
                    .orderByDesc(SysDictItem::getCreateTime);
            Page<SysDictItem> itemPage = sysDictItemService.page(page, itemQueryWrapper);
            Page<SysDictItemVO> items = ConvertUtils.toPage(itemPage, item -> {
                SysDictItemVO vo = new SysDictItemVO();
                BeanUtils.copyProperties(item, vo);
                return vo;
            });
            return Result.success(items);
        } else {
            return Result.success(null);
        }
    }
}
